﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using System.Text;



namespace Plovius
{
    class PloviusClient
    {
        private String str_TargetIP = "192.168.1.5";
        private String str_Password = "test123";
        private int int_Port = 3000;
        private int int_ConAttempts = 0;
        private bool bool_Connected = false;
        private bool bool_AllowAction = false;
        ASCIIEncoding encoder = new ASCIIEncoding();
        private Thread thread_Connect;
        private Thread thread_Connecting;
        NetworkStream clientStream;
        private TcpClient myClient = null;
        private IPEndPoint serverEndPoint;

        public static void Main()
            {
                PloviusClient client = new PloviusClient();
                client.Start();
            }


        private void Connecting()
        {
            int_ConAttempts++;
            while (bool_Connected == false)
            {
                try
                {
                    myClient.Connect(serverEndPoint);
                    clientStream = myClient.GetStream();
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine(e.ToString());
                }
            }

            /*
             * Now we sleep so we make sure server is ready
             * after that.. we send server password wait for confirmation
             * if we get a confirm we grant access to send data
             */

            Thread.Sleep(3000);
            this.SendPassword();

            while (true)
            {
                int bytesRead = 0;
                try
                {
                    bytesRead = clientStream.ReadByte();
                }
                catch
                {
                    // Wait 
                }
            }

            // Now we are 100% ready
            if (int_ConAttempts < 5)
                bool_AllowAction = true;
            else
                this.Close();
        }

        private void Controller()
        {
            /* Just a small control support checking for connection 
             * If we are connected do something */
            try
            {
                if (myClient != null)
                {
                    while (true)
                    {
                        if (myClient != null)
                            if (myClient.Connected == true)
                            {
                                if (bool_Connected == false)
                                {
                                    bool_Connected = true;
                                    break;
                                }
                            }
                    }
                }
            }
            catch (Exception e)
            {
                // If we get to this point its pretty much most likely its because client is already shutted down
                System.Diagnostics.Debug.WriteLine(e.ToString());
            }
        }

        private void SendByte(byte value)
        {
            try
            {
                byte buffer = value;
                if (clientStream.CanWrite)
                {
                    clientStream.WriteByte(buffer);
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.WriteLine(e.ToString());
            }
        }

        private void SendPassword()
        {
            // We need this to send some data without having access from bool_AllowAction
            byte[] buffer = encoder.GetBytes(str_Password);
            if (clientStream.CanWrite)
            {
                clientStream.Write(buffer, 0, buffer.Length);
                clientStream.Flush();
            }            
        }  

        private void ObtainData()
        {
            while (true)
            {
                int bytesRead = 0;
                byte [] bytes = new byte[1024];
                try
                {
                    bytesRead = clientStream.Read(bytes, 0, 1024);
                }
                catch
                {
                    // Wait 
                }
            }
        }


        public void Start()
        {
            serverEndPoint = new IPEndPoint(IPAddress.Parse(str_TargetIP), int_Port);
            myClient = new TcpClient();

            this.thread_Connecting = new Thread(new ThreadStart(Connecting));
            this.thread_Connect = new Thread(new ThreadStart(Controller));
            this.thread_Connecting.Start();
            this.thread_Connect.Start();
        }



        public void SendText(string txt)
        {
            if (bool_AllowAction)
            {
                byte[] buffer = encoder.GetBytes(txt);   
                if (clientStream.CanWrite)
                {
                    clientStream.Write(buffer, 0, buffer.Length);
                    clientStream.Flush();
                }
                while (true)
                {
                    int bytesRead = 0;
                    try
                    {
                        bytesRead = clientStream.ReadByte();
                    }
                    catch
                    {
                        // Wait 
                    }
                }
            }
        }

        public bool isConnected()
        {
            // Return's true if connected
            return bool_Connected;
        }

        public void Close()
        {
            if (myClient != null)
            {
                myClient.Close();
            }
            if (clientStream != null)
            {
                clientStream.Close();
            }
        }


        public void setIpAddr(string value)
        {
            this.str_TargetIP = value;
        }

        public void setPassword(string value)
        {
            str_Password = value;
        }

    }
}
